package com.smart.speaker.websocket;

import com.smart.speaker.util.StrUtils;

import java.util.List;

public class SessionState {

    /** 只在Socket线程中修改 */
    private volatile State state;

    /** 只在Socket的线程中使用 */
    private long listenStartTime = 0;
    /** 只在Socket的线程中使用 */
    private long idleStartTime;
    /** 下面的都需要线程同步 */
    private long lastSpeakTime = 0;
    private StringBuilder request;
    private StringBuilder response;
    private int responseTrigger = 0;

    public SessionState() {
        this.state = State.IDLE;
        this.idleStartTime = System.currentTimeMillis();
    }

    public synchronized void updateLastSpeakTime() {
        this.lastSpeakTime = System.currentTimeMillis();
    }

    public synchronized int getSilenceDuration() {
        // 如果未检测到静音，返回0
        if (lastSpeakTime == 0) {
            return 0;
        }
        // 返回从上次检测到静音到现在的时间差
        return (int) (System.currentTimeMillis() - lastSpeakTime);
    }

    public int getListeningDuration() {
        // 如果未开始监听，返回0
        if (listenStartTime == 0) {
            return 0;
        }
        // 返回从开始监听到现在的时间差
        return (int) (System.currentTimeMillis() - listenStartTime);
    }

    public int getIdleDuration() {
        // 如果未进入空闲状态，返回0
        if (idleStartTime == 0) {
            return 0;
        }
        // 返回从进入空闲状态到现在的时间差
        return (int) (System.currentTimeMillis() - idleStartTime);
    }

    public boolean isIdle() {
        return state == State.IDLE;
    }

    public boolean isListening() {
        return state == State.LISTENING;
    }

    public boolean isSpeaking() {
        return state == State.SPEAKING;
    }

    public void changeToIdle() {
        if (state == State.IDLE) {
            return;
        }
        state = State.IDLE;
        idleStartTime = System.currentTimeMillis();
        listenStartTime = 0;

        synchronized (this) {
            lastSpeakTime = 0;
            responseTrigger = 0;
            request = null;
            response = null;
        }
    }

    public void changeToListening() {
        if (state == State.IDLE) {
            state = State.LISTENING;
            listenStartTime = System.currentTimeMillis();
        }
    }

    public void changeToSpeaking() {
        state = State.SPEAKING;
    }

    public synchronized void appendRequest(String str) {
        if (request == null) {
            request = new StringBuilder();
        }
        request.append(str);
    }

    public synchronized String getRequest() {
        return request == null || request.isEmpty() ? null : request.toString();
    }

    public synchronized void appendResponse(String str) {
        if (response == null) {
            response = new StringBuilder();
        }
        response.append(str);
    }

    public synchronized String getSentence() {
        if (response == null || response.isEmpty()) {
            return null;
        }
        for (String endpoint : StrUtils.endpoints) {
            int i = response.indexOf(endpoint, responseTrigger);
            if (i != -1) {
                String res = response.substring(responseTrigger, i + endpoint.length());
                responseTrigger = i + endpoint.length();
                return res;
            }
        }
        return null;
    }

    public synchronized String getLastSentence() {
        if (response == null || response.isEmpty()) {
            return null;
        }
        if (responseTrigger >= response.length()) {
            return null;
        }
        return response.substring(responseTrigger);
    }

    public synchronized String getResponse() {
        return response == null || response.isEmpty() ? null : response.toString();
    }

    private enum State {
        IDLE,
        LISTENING,
        SPEAKING,
    }
}
